# -*- encoding: utf-8 -*-
import logging

from odoo.addons.base_cw.public import merge_line
from odoo.exceptions import UserError

from odoo import models, fields

_logger = logging.getLogger(__name__)


class StockPicking(models.Model):
    _inherit = 'stock.picking'

    def generate_account_voucher(self):
        """
        生成会计凭证
        :return:
        """
        # self.ensure_one()z
        # self._data_check()
        for record in self:
            sudo_script_lines = record.script_line_ids.filtered(lambda r: not r.voucher_id and not r.invoice_id)
            sudo_script_lines2 = record.script_line_ids.filtered(lambda r: not r.voucher_id and r.invoice_id)
            record._generate_account_voucher(sudo_script_lines)
            record._generate_account_voucher(sudo_script_lines2)

    def _generate_account_voucher(self, sudo_script_lines):
        # _logger.info("_________________生成凭证__________________")

        if sudo_script_lines:
            voucher_id = self.env['account.voucher'].create(dict(
                date=fields.Date.context_today(self),
                origin=self.picking_type_id.script_template_id.note if self.picking_type_id.script_template_id.note else '' + ':' + self.name,
                voucher_category_id=self.picking_type_id.script_template_id.voucher_category_id.id
            ))
            # _logger.info("_________________生成凭证ID__________________%s" % voucher_id.id)
            items = []
            for x in sudo_script_lines:
                sub_account_lines_data = []
                sub_account_ids = []
                for line in x.sub_account_lines:
                    sub_account_id = line.sub_account_id.id
                    if sub_account_id not in sub_account_ids:
                        sub_account_ids.append(sub_account_id)
                        line_data = {'category_id': line.category_id.id, 'sub_account_id': sub_account_id}
                        sub_account_lines_data.append((0, 0, line_data))

                item = dict(sequence=x.sequence,
                            dc_type=x.dc_type,
                            account_id=x.account_id.id,
                            sub_account_id=x.sub_account_id and x.sub_account_id.id or False,
                            name=x.name,
                            currency_id=x.currency_id and x.currency_id.id or False,
                            exchange_rate=x.exchange_rate,
                            debit=x.debit or False,
                            credit=x.credit or False,
                            lc_debit=x.lc_debit,
                            lc_credit=x.lc_credit,
                            sub_account_lines=sub_account_lines_data,
                            company_id=x.company_id and x.company_id.id or False,
                            move_ids=[(6, 0, x.move_ids.ids)]
                            )
                items.append((0, 0, item))
            # _logger.info("_________________凭证写入__________________%s" % items)
            voucher_id.write(dict(line_ids=items))
            sudo_script_lines.write(dict(voucher_id=voucher_id.id))

    # def action_done(self):
    #     res = super(StockPicking, self).action_done()
    #     sudo_picking = self.filtered(lambda r: r.picking_type_id.script_template_id)
    #     # 生成预切凭证明细
    #     sudo_picking.create_account_voucher_script_line_id()
    #     # 生成正式凭证
    #     sudo_picking.generate_account_voucher()
    #     return res

    def button_validate(self):
        res = super(StockPicking, self).button_validate()
        if len(self.move_ids_without_package) <= 1 and 0.0 in self.move_ids_without_package.mapped('quantity'):
            # 当作业明细小于等于1条，完成数存在0时跳过
            return res
        elif len(self.move_ids_without_package) > 1 and len(set(self.move_ids_without_package.mapped('quantity'))) == 1 and 0 in set(self.move_ids_without_package.mapped('quantity')):
            # 当作业明细大于1条，完成数只有0时跳过
            return res
        else:
            if type(res) == bool :
                # 类型为bool的时候执行
                sudo_picking = self.filtered(lambda r: r.picking_type_id.script_template_id)
                # 生成预切凭证明细
                sudo_picking.create_account_voucher_script_line_id()
                # 生成正式凭证
                sudo_picking.generate_account_voucher()
        return res

    def generate_account_voucher_script_line(self):
        """
        产生预切凭证明细
        :return:
        """
        # _logger.info("_________________生产预切凭证明细_________________")
        for picking_id in self:
            # picking_id.script_line_ids = False
            # 1.借方
            script_template_id = picking_id.picking_type_id.script_template_id
            # 暂估凭证
            voucher_category_99 = self.env.ref('cncw_ledger.account_voucher_category_99')
            move_lines = picking_id.move_ids.filtered(
                lambda r: r.product_id.product_type not in script_template_id.product_type_ids.mapped('product_type') and r.quantity > 0)
            # 根据成本类型取会计科目
            account_amount = {}
            exchange_rate = 1
            currency_id = self.env['res.currency']
            for move_id in move_lines:
                # currency_id = move_id.currency_id
                # exchange_rate = currency_id.rate
                # if exchange_rate == 0:
                #     raise UserError('货币汇率为0，请检查好后再试！请联系管理员！')
                move_amount=0
                # 遍历凭证模版
                for line_id in script_template_id.get_dc_type_line_ids(product_type=move_id.product_id.product_type):
                    # 获取产品不含税单价
                    if move_id.local_amount_untaxed<=0 or move_id.local_price<=0 or not move_id.local_amount_untaxed or not move_id.local_price:
                        move_id._compute_local_amount()
                    move_amount = move_id.price_unit
                    # # 产品单价 ==  取产品平均价
                    # if not move_amount:
                    #
                    #     move_amount = move_id.local_price
                    if line_id.master_id.code == 'purchase' or script_template_id.voucher_category_id == voucher_category_99:
                    #     # move_amount = move_id.local_price
                    #     # 获取产品不含税单价
                        if move_id.local_amount_untaxed == 0:
                            move_id._compute_local_amount()
                        if move_id.product_qty != 0:
                            move_amount = move_id.local_amount_untaxed/move_id.product_qty
                        else:
                            move_amount = 0
                    account_id = line_id.get_account_id()
                    # 模版有借贷方
                    if line_id.dc_type:
                        # 取凭证模版借贷方
                        account_id.dc_type = line_id.dc_type
                    # 直接材料
                    if account_id.code == '50010101' and account_id.dc_type == 'C':
                        move_amount = move_id.price_unit
                    # 人工成本
                    if account_id.code == '50010102':
                        move_amount = move_id.avg_labor
                    # 平均材料
                    if account_id.code == '50010103':
                        move_amount = move_id.avg_overhead
                    # if move_amount == 0:
                    #     raise UserError('未取值到产品货币单价！请联系管理员！')
                    move_amount = move_amount * move_id.product_qty
                    amount_sub_total = account_amount.get(account_id, 0) + move_amount
                    account_amount[account_id] = amount_sub_total
            # end
            name = picking_id.name
            items = []
            for k, amount in account_amount.items():
                sub_account_lines_data = []
                sub_account_ids = []
                sub_account_id = picking_id.partner_id.id
                for line in k.get_subaccount_category_ids():
                    if sub_account_id not in sub_account_ids:
                        sub_account_ids.append(sub_account_id)
                        line_data = {'category_id': line.id, 'sub_account_id': picking_id.partner_id.id or False}
                        sub_account_lines_data.append((0, 0, line_data))
                if k.sub_account_type == 'has' and sub_account_id not in sub_account_ids:
                    sub_account_ids.append(sub_account_id)
                    sub_account_lines_data.append(
                        (0, 0, {'category_id': picking_id.partner_id.subaccount_category_id.id,
                                'sub_account_id': sub_account_id or False}))

                product_name = ';产品:%s' % '、'.join(
                    [product.display_name for product in move_lines.mapped('product_id')])
                tmp_item = dict(
                    dc_type=k.dc_type,
                    picking_id=picking_id.id,
                    debit=amount if k.dc_type == 'D' else 0,
                    lc_debit=amount * exchange_rate if k.dc_type == 'D' else 0,
                    credit=amount if k.dc_type == 'C' else 0,
                    lc_credit=amount * exchange_rate if k.dc_type == 'C' else 0,
                    currency_id=currency_id.id or False,
                    exchange_rate=exchange_rate or 1.0,
                    account_id=k.id,
                    name=script_template_id.note if script_template_id.note else '' + ':' + name + product_name,
                    sub_account_id=picking_id.partner_id.id,
                    sub_account_lines=sub_account_lines_data
                )
                items.append((0, 0, tmp_item))

            items = merge_line(self, items)
            # _logger.info("_________________预切凭证写入__________________%s" % items)
            if items:
                picking_id.write(dict(script_line_ids=items))
                for script_line_id in picking_id.script_line_ids:
                    script_line_id.move_ids = move_lines
            return

    def create_account_voucher_script_line_id(self):
        self.generate_account_voucher_script_line()
        return

    script_line_ids = fields.One2many('account.voucher.script.line', 'picking_id', string=u'暂估凭证')
